#ifdef __linux__
#include <cstdio>
#include <cstddef>
#include <cstdlib>
#include <new>
#include <stdio.h>
#include <map>
#include <iostream>
#include<execinfo.h>
#include<cxxabi.h>
#include<unistd.h>
std::string addr_to_symbol(void *addr);
pthread_mutex_t mutex;

struct AllocatedInfo
{
    void *ptr;
    size_t size;
    void *caller;
};
std::map<void*, AllocatedInfo> allocated;
bool enable = false;
void* operator new(size_t size);
void operator delete(void* ptr) noexcept;
struct Global{
    Global():_enable(true)
    {
        pthread_mutex_init(&mutex,NULL);
    }
    ~Global()
    {
        enable = false;
        for(const auto &pair:allocated)
        {
            std::string caller=addr_to_symbol(pair.second.caller);
            
            printf("内存泄漏 ptr =%p,size =%zd, caller =%s\n",pair.first,pair.second.size,caller.c_str());
        }
    }
    bool _enable;
}global;
std::string addr_to_symbol(void *addr)
{
    char exe_path[512];
    ssize_t len = readlink("/proc/self/exe", exe_path, sizeof(exe_path) - 1);
    if (len != -1) {
        exe_path[len] = '\0';
    } else {
        std::cerr << "Error reading executable path" << std::endl;
        return "unknown";
    }

    char cmd[512];
    snprintf(cmd, sizeof(cmd), "addr2line -f -p -e %s %p", exe_path, addr);

    FILE* fp = popen(cmd, "r");
    if (!fp) {
        std::cerr << "Error executing addr2line command" << std::endl;
        return "unknown";
    }

    char buf[512];
    std::string result;
    while (fgets(buf, sizeof(buf), fp)) {
        result += buf;
    }
    pclose(fp);

    // 移除末尾的换行符
    if (!result.empty() && result[result.size() - 1] == '\n') {
        result.pop_back();
    }
    //解码函数名
    size_t end=result.find(" ");
    std::string _result;
    if(end!=std::string::npos)
    {
         _result=result.substr(0,end);
    }
    size_t second_blank=result.find(" ",end+1);
    std::string pos_line=result.substr(second_blank,result.length()-end);
    const char* mangled_name = _result.c_str();
    int status;
    char* demangled_name;

    // 使用 abi::__cxa_demangle 解析 mangled 名称
    demangled_name = abi::__cxa_demangle(mangled_name, nullptr, nullptr, &status);
    if(demangled_name)
    result=demangled_name+pos_line;
    else
    result="main"+pos_line;
    // 释放由 abi::__cxa_demangle 分配的内存
    if(demangled_name)
    free(demangled_name);
  

    return result;
}

void* operator new(size_t size)
{
   pthread_mutex_lock(&mutex);
   bool was_enable = global._enable;
   global._enable=false;
   pthread_mutex_unlock(&mutex);
    void* ptr = malloc(size);
    if (was_enable)
    {
        void *caller= __builtin_return_address(0);
        if (ptr) 
        {
            enable = false;
            printf("new: ptr = %p, size = %zd\n", ptr, size);
            allocated.insert(std::make_pair(ptr, AllocatedInfo{ptr,size,caller}));
        }
    }
    pthread_mutex_lock(&mutex);
    global._enable=was_enable;
    pthread_mutex_unlock(&mutex);
    if (ptr == nullptr)
        throw std::bad_alloc();
    return ptr;
}
void operator delete(void* ptr) noexcept
{
   pthread_mutex_lock(&mutex);
   bool was_enable = global._enable;
   global._enable=false;
   pthread_mutex_unlock(&mutex);
    if(ptr==nullptr)
    return;
    printf("delete: ptr = %p\n", ptr);
    std::map<void*,AllocatedInfo>::iterator _it = allocated.find(ptr);
    if (_it != allocated.end()) {
        allocated.erase(_it);
    }
    pthread_mutex_lock(&mutex);
    global._enable=was_enable;
    pthread_mutex_unlock(&mutex);
    free(ptr);
}
void operator delete[](void* ptr) noexcept {
   pthread_mutex_lock(&mutex);
   bool was_enable = global._enable;
   global._enable=false;
   pthread_mutex_unlock(&mutex);
    if (ptr == nullptr)
        return;
    std::cout << "delete[]: ptr = " << ptr << std::endl;
    auto _it = allocated.find(ptr);
    if (_it != allocated.end()) {
        allocated.erase(_it);
    }
    pthread_mutex_lock(&mutex);
    global._enable=was_enable;
    pthread_mutex_unlock(&mutex);
    free(ptr);
}
void operator delete[](void* ptr, std::nothrow_t) noexcept {
   pthread_mutex_lock(&mutex);
   bool was_enable = global._enable;
   global._enable=false;
   pthread_mutex_unlock(&mutex);
    if (ptr == nullptr)
        return;
    else if(ptr) {
        auto it = allocated.find(ptr);
        if (it != allocated.end()) {
            printf("delete[]: ptr = %p, size = %zd\n", it->second.ptr, it->second.size);
            allocated.erase(it);
        }
        free(ptr);
    }
}
void *operator new[](size_t size, std::nothrow_t const &) noexcept {
   pthread_mutex_lock(&mutex);
   bool was_enable = global._enable;
   global._enable=false;
   pthread_mutex_unlock(&mutex);
    void* ptr = malloc(size);
    if (was_enable)
    {
        void *caller= __builtin_return_address(0);
        if (ptr) 
        {
            enable = false;
            printf("new: ptr = %p, size = %zd\n", ptr, size);
            allocated.insert(std::make_pair(ptr, AllocatedInfo{ptr,size,caller}));
        }
    }
    pthread_mutex_lock(&mutex);
    global._enable=was_enable;
    pthread_mutex_unlock(&mutex);
    if (ptr == nullptr)
        throw std::bad_alloc();
    return ptr;
}
#elif _WIN32
#include <cstdio>
#include <cstddef>
#include <cstdlib>
#include <new>
#include <stdio.h>
#include <map>
#include <iostream>
#include <windows.h>
#include <dbghelp.h>
#include <mutex>
#include <string>
#include <intrin.h>

// 函数声明
std::string addr_to_symbol(void* addr);

// 全局变量和结构体
std::mutex global_mutex;

struct AllocatedInfo {
    void* ptr;
    size_t size;
    void* caller;
};
std::map<void*, AllocatedInfo> allocated;
bool enable = false;

// 重载的 new 和 delete 操作符
void* operator new(size_t size);
void operator delete(void* ptr) noexcept;
void operator delete[](void* ptr) noexcept;
void* operator new[](size_t size, std::nothrow_t const&) noexcept;
void operator delete[](void* ptr, std::nothrow_t) noexcept;
// 全局变量，用于管理分配状态和内存泄漏检测
struct Global {
    Global() : _enable(true) {
        SymInitialize(GetCurrentProcess(), NULL, TRUE);
    }
    ~Global() {
        enable = false;
        for (const auto& pair : allocated) {
            std::string caller = addr_to_symbol(pair.second.caller);
            printf("内存泄漏 ptr = %p, size = %zd, caller = %s\n", pair.first, pair.second.size, caller.c_str());
        }
        SymCleanup(GetCurrentProcess());
    }
    bool _enable;
} global;

// 地址转符号的函数实现
std::string addr_to_symbol(void* addr) {
    DWORD64  dwDisplacement = 0;
    DWORD64  dwAddress = (DWORD64)addr;

    HANDLE process = GetCurrentProcess();
    SYMBOL_INFO* symbol = (SYMBOL_INFO*)malloc(sizeof(SYMBOL_INFO) + 256 * sizeof(char));
    symbol->MaxNameLen = 255;
    symbol->SizeOfStruct = sizeof(SYMBOL_INFO);

    std::string result;
    if (SymFromAddr(process, dwAddress, &dwDisplacement, symbol)) {
        result = symbol->Name;
        IMAGEHLP_LINE64 line;
        DWORD dwDisplacement;
        if (SymGetLineFromAddr64(process, dwAddress, &dwDisplacement, &line)) {
            result += " at " + std::string(line.FileName) + ":" + std::to_string(line.LineNumber);
        }
    }
    else {
        result = "Unknown symbol";
    }

    free(symbol);
    return result;
}

// 重载的 new 操作符
void* operator new(size_t size) {
    std::lock_guard<std::mutex> lock(global_mutex);
    bool was_enable = global._enable;
    global._enable = false;

    void* ptr = malloc(size);
    if (was_enable) {
        void* caller = _ReturnAddress();
        if (ptr) {
            printf("new: ptr = %p, size = %zd\n", ptr, size);
            allocated.insert(std::make_pair(ptr, AllocatedInfo{ ptr, size, caller }));
        }
    }

    global._enable = was_enable;

    if (ptr == nullptr) {
        throw std::bad_alloc();
    }

    return ptr;
}

// 重载的 delete 操作符
void operator delete(void* ptr) noexcept {
    std::lock_guard<std::mutex> lock(global_mutex);
    bool was_enable = global._enable;
    global._enable = false;

    if (ptr == nullptr) {
        return;
    }

    printf("delete: ptr = %p\n", ptr);
    auto _it = allocated.find(ptr);
    if (_it != allocated.end()) {
        allocated.erase(_it);
    }

    global._enable = was_enable;

    free(ptr);
}

void operator delete[](void* ptr) noexcept {
    std::lock_guard<std::mutex> lock(global_mutex);
    bool was_enable = global._enable;
    global._enable = false;

    if (ptr == nullptr) {
        return;
    }

    std::cout << "delete[]: ptr = " << ptr << std::endl;
    auto _it = allocated.find(ptr);
    if (_it != allocated.end()) {
        allocated.erase(_it);
    }

    global._enable = was_enable;

    free(ptr);
    }

    // 重载的 nothrow new 操作符
        void* operator new[](size_t size, std::nothrow_t const&) noexcept {
        std::lock_guard<std::mutex> lock(global_mutex);
        bool was_enable = global._enable;
        global._enable = false;

        void* ptr = malloc(size);
        if (was_enable) {
            void* caller = _ReturnAddress();
            if (ptr) {
                printf("new[]: ptr = %p, size = %zd\n", ptr, size);
                allocated.insert(std::make_pair(ptr, AllocatedInfo{ ptr, size, caller }));
            }
        }

        global._enable = was_enable;

        return ptr;
        }

        void operator delete[](void* ptr, std::nothrow_t) noexcept {
            std::lock_guard<std::mutex> lock(global_mutex);
            bool was_enable = global._enable;
            global._enable = false;

            if (ptr == nullptr) {
                return;
            }

            auto it = allocated.find(ptr);
            if (it != allocated.end()) {
                printf("delete[]: ptr = %p, size = %zd\n", it->second.ptr, it->second.size);
                allocated.erase(it);
            }

            free(ptr);
            }

#endif